class Delivery < ActiveRecord::Base
  include DeliveryStatus
  include RedisAware

  belongs_to :promotion_mail
  belongs_to :admin

  after_initialize {@process = DeliveryProcess.new(self)}

  def start(recipients)
    black_list = InvalidUser.all.select(:user_id).to_a.map(&:user_id)
    domains = Domain.where(name: domain_name).take || Domain.where.not(name: SPECIAL_DOMAINS).to_a
    to = recipients.where(domain: domains, subscribe: true).where.not(id: black_list).order(last_sign_in: :desc).select(:id).map(&:id)
    return if to.empty?
    @redis_main.rpush @process.queue_name, to
    @process.start do |recipient_ids|
      deliver_to_recipients(recipient_ids)
    end
  end

  def sent
    return delivered if delivered > 0
    total - @redis_main.llen(@process.queue_name)
  end

  def can_start?
    status.to_sym == DeliveryStatus::NOT_STARTED
  end

  def can_pause?
    status.to_sym == DeliveryStatus::SENDING
  end

  def can_resume?
    status.to_sym == DeliveryStatus::PAUSE
  end

  def can_stop?
    status.to_sym.in? [DeliveryStatus::SENDING, DeliveryStatus::PAUSE]
  end

  def can_hang?
    true
  end

  def resume
    return unless can_resume?
    @process.resume do |recipient_ids|
      deliver_to_recipients(recipient_ids)
    end
  end

  %i(pause stop hang).each do |action|
    define_method action do                          # def pause
      return unless public_send("can_#{action}?")    #   return unless can_pause?
      @process.public_send action                    #   @process.pause
    end                                              # end
  end

  private
  def deliver_to_recipients(recipient_ids)
    recipients = User.where(id: recipient_ids)
    PromotionMailer.promote(promotion_mail, recipients).deliver
  end

end
